package com.itttq.gen.controller;

import com.google.code.kaptcha.Producer;
import com.itttq.gen.common.conf.GenProperties;
import com.itttq.gen.common.constant.Constants;
import com.itttq.gen.generator.TableInfo;
import com.itttq.gen.model.po.AccountPo;
import com.itttq.gen.model.po.ProjectPo;
import com.itttq.gen.model.to.ResultTo;
import com.itttq.gen.service.AccountService;
import com.itttq.gen.utils.Base64Util;
import com.itttq.gen.utils.DbUtil;
import com.itttq.gen.utils.GenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 验证码操作处理
 */
@RestController
@Slf4j
public class CommonController extends BaseController {
    @Autowired
    private Producer captchaProducer;
    @Autowired
    private AccountService accountService;
    @Autowired
    private GenProperties genProps;

    @PostMapping("/login")
    public AccountPo login(@RequestBody @Validated AccountPo account) {
        // 判断是不是超过三次错误
        Object loginTimesObj = this.getSession().getAttribute(Constants.SESSION_LOGIN_TIMES);
        int loginTimes = null == loginTimesObj ? 0 : (Integer) loginTimesObj;
        loginTimes++;
        this.getSession().setAttribute(Constants.SESSION_LOGIN_TIMES, loginTimes);
        if (3 < loginTimes) {
            // 校验验证码
            Assert.isTrue(verifyCaptcha(account.getCode()), ResultTo.getCodeAndMsg(ResultTo.ResultCode.CODE_ERR));
        }
        AccountPo accountPo = accountService.login(account.getUsername(), account.getPassword());
        this.getSession().removeAttribute(Constants.SESSION_LOGIN_TIMES);
        this.getSession().setAttribute(Constants.SESSION_ACCOUNT, accountPo);
        return accountPo;
    }

    @PostMapping("/logout")
    public void logout() {
        // session失效
        invalidate();
    }

    /**
     * 生成验证码，前端需要在生成的base64字符串前加：data:image/jpg;base64,
     */
    @GetMapping("vc")
    public String getCaptcha() {
        // 生成验证码
        String code = captchaProducer.createText();
        BufferedImage image = captchaProducer.createImage(code);
        // 采用sessionID作为唯一标识
        this.getSession().setAttribute(Constants.SESSION_CAPTCHA, code);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            log.error("生成验证码图片异常", e);
        }

        return Base64Util.encode(os.toByteArray());
    }

    /**
     * 验证验证码
     */
    @GetMapping("/vc/verify")
    public boolean verifyCaptcha(String code) {
        if (StringUtils.isEmpty(code)) {
            return false;
        }
        Object codeStr = this.getSession().getAttribute(Constants.SESSION_CAPTCHA);
        // 验证后则删除验证码
        this.getSession().removeAttribute(Constants.SESSION_CAPTCHA);
        return code.equals(codeStr);
    }

    @PostMapping("/test/db")
    public boolean testDbConn(@RequestBody ProjectPo projectPo) {
        DbUtil dbUtil = DbUtil.getDbUtil(projectPo);
        boolean rs = null != dbUtil;
        if (rs) {
            dbUtil.closeConn();
        }
        return rs;
    }

    @PostMapping("/test/redis")
    public boolean testRedisConn(@RequestBody ProjectPo project) {
        return GenUtil.getRedisIsOk(project.getRedisHost(), project.getRedisPort(), project.getRedisPassword());
    }

    /**
     * 上传文件方法
     *
     * @param file
     * @return
     */
    @PostMapping("/uploadFile")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return null;
        }
        AccountPo account = getAccount();
        // 获取新的文件名和后缀
        String fileName = System.nanoTime() + file.getOriginalFilename().substring(file.getOriginalFilename().indexOf(Constants.DOT));
        try {
            // 判断文件夹是否存在
            File destDir = new File(genProps.getSqlFlord() + account.getId());
            // 如果不存在则创建
            if (!destDir.exists()) {
                destDir.mkdirs();
            }
            file.transferTo(new File(destDir.getPath() + fileName));
        } catch (Exception e) {
            log.error("上传异常", e);
        }
        return genProps.getSqlDownloadUrl(account.getId() + Constants.SLASH + fileName);
    }
}
